﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartMathLibrary.LinearEquationSolvers
{
    /// <summary>
    /// This class provides the solving of a linear system of equation by using the inverse matrix.
    /// </summary>
    [Serializable]
    public class InverseLinearSystemSolver
    {
        /// <summary>
        /// The system of equation to solve.
        /// </summary>
        private readonly LinearEquationSystem equationSystem;

        /// <summary>
        /// Initializes a new instance of the <see cref="InverseLinearSystemSolver"/> class.
        /// </summary>
        /// <param name="coefficientMatrix">The coefficient matrix of the equation system to solve.</param>
        /// <param name="resultVector">The result vector of the equation system to solve.</param>
        public InverseLinearSystemSolver(Matrix coefficientMatrix, GeneralVector resultVector)
        {
            this.equationSystem = new LinearEquationSystem(coefficientMatrix, resultVector);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InverseLinearSystemSolver"/> class.
        /// </summary>
        /// <param name="equationSystem">The system of equation to solve.</param>
        public InverseLinearSystemSolver(LinearEquationSystem equationSystem)
        {
            this.equationSystem = equationSystem;
        }

        /// <summary>
        /// Gets or sets the coefficient matrix of the equation system to solve.
        /// </summary>
        /// <value>The coefficient matrix of the equation system to solve.</value>
        public Matrix CoefficientMatrix
        {
            get { return equationSystem.CoefficientMatrix; }
            set { equationSystem.CoefficientMatrix = value; }
        }

        /// <summary>
        /// Gets or sets the result vector of the equation system to solve.
        /// </summary>
        /// <value>The result vector of the equation system to solve.</value>
        public GeneralVector ResultVector
        {
            get { return equationSystem.ResultVector; }
            set { equationSystem.ResultVector = value; }
        }

        /// <summary>
        /// Solves the linear system of equation by using the inverse matrix of the coefficient matrix.
        /// </summary>
        /// <returns>The results of the system of equation.</returns>
        public GeneralVector SolveLinearSystem()
        {
            if (!this.CoefficientMatrix.IsSquareMatrix)
            {
                throw new ArgumentException(
                    "The coefficient matrix of the system of equation has to be a square matrix.");
            }

            Matrix inverse = InverseMatrix.FromMatrix(new SquareMatrix(this.CoefficientMatrix));

            return inverse * this.ResultVector;
        }
    }
}